<template>
  <div id="kline">
    <div class="iflex tools">
      <div class="topic">
        <slot/>
      </div>
      <div class="iflex">
        <div @click="showPopup = true">
          指标
        </div>
        <div class="iflex">
          <div v-if="showPeriods.indexOf('h') > -1" :style="{ color: period === 'h' ? '#e6a23c' : '#ffffff' }"
               @click="onChange('h')">
            时
          </div>
          <div v-if="showPeriods.indexOf('d') > -1" :style="{ color: period === 'd' ? '#e6a23c' : '#ffffff' }"
               @click="onChange('d')">日
          </div>
          <div v-if="showPeriods.indexOf('w') > -1" :style="{ color: period === 'w' ? '#e6a23c' : '#ffffff' }"
               @click="onChange('w')">周
          </div>
          <div v-if="showPeriods.indexOf('m') > -1" :style="{ color: period === 'm' ? '#e6a23c' : '#ffffff' }"
               @click="onChange('m')">月
          </div>
        </div>
      </div>
    </div>
    <div id="chart"/>
    <div id="popup" v-show="showPopup">
      <div>
        <div class="title iflex">
          <div>主图指标</div>
          <div class="close" @click="showPopup=false">x</div>
        </div>
        <div class="index">
          <div class="check" v-for="item in mainIndicators" :key="item.name">
            <input type="checkbox" :checked="item.checked" @change="changeMainIndicator(item.name)"/>
            <label>{{ item.name }}({{ item.sub }})</label>
          </div>
        </div>
        <div class="title">副图指标</div>
        <div class="index">
          <div class="check" v-for="item in subIndicators" :key="item.name">
            <input type="checkbox" :checked="item.checked" @change="changeSubIndicator(item.name)"/>
            <label>{{ item.name }}({{ item.sub }})</label>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {init} from 'klinecharts'

export default {
  props: {
    data: {
      type: Array,
      default: []
    },
    showPeriods: {
      type: Array,
      default: () => (['h', 'd', 'w', 'm'])
    }
  },
  data() {
    return {
      chart: null,
      period: 'd',
      showPopup: false,
      mainIndicators: [
        {
          type: 'main',
          checked: true,
          name: 'MA',
          sub: '移动平均线',
          params: [5, 10, 20, 60, 120, 250]
        },
        {
          type: 'main',
          checked: false,
          name: 'EMA',
          sub: '指数平滑移动平均线',
          params: [6, 12, 20],
        },
        {
          type: 'main',
          checked: false,
          name: 'SMA',
          sub: '简单移动平均线',
          params: [12, 2],
        },
        {
          type: 'main',
          checked: false,
          name: 'BOLL',
          sub: '布林轨道',
          params: [20, 2],
        },
        {
          type: 'main',
          checked: false,
          name: 'SAR',
          sub: '停损点指向',
          params: [2, 2, 20],
        },
        {
          type: 'main',
          checked: false,
          name: 'BBI',
          sub: '多空指数',
          params: [3, 6, 12, 24],
        },
      ],
      subIndicators: [
        {
          type: 'sub',
          checked: true,
          name: 'VOL',
          sub: '成交量',
          params: [5, 10, 20],
        },
        {
          type: 'sub',
          checked: false,
          name: 'MACD',
          sub: '平滑异同移动平均线',
          params: [12, 26, 9],
        },
        {
          type: 'sub',
          checked: false,
          name: 'KDJ',
          sub: '随机指标',
          params: [9, 3, 3],
        },
        {
          type: 'sub',
          checked: false,
          name: 'RSI',
          sub: '相对强弱指标',
          params: [6, 12, 24],
        },
        {
          type: 'sub',
          checked: false,
          name: 'OBV',
          sub: '能量潮指标',
          params: [30],
        },
        {
          type: 'sub',
          checked: false,
          name: 'BIAS',
          sub: '乖离率',
          params: [26],
        },
        {
          type: 'sub',
          checked: false,
          name: 'DMI',
          sub: '动向',
          params: [14, 6],
        },
        {
          type: 'sub',
          checked: false,
          name: 'CCI',
          sub: '超买超卖',
          params: [13],
        },
        {
          type: 'sub',
          checked: false,
          name: 'WR',
          sub: '威廉',
          params: [6, 10, 14],
        },
        {
          type: 'sub',
          checked: false,
          name: 'EMV',
          sub: '简单波动',
          params: [14, 9],
        },
        {
          type: 'sub',
          checked: false,
          name: 'TRIX',
          sub: '三重指数平滑平均线',
          params: [12, 20],
        },
        {
          type: 'sub',
          checked: false,
          name: 'DMA',
          sub: '平行线差指标',
          params: [10, 50, 10],
        },
        {
          type: 'sub',
          checked: false,
          name: 'PSY',
          sub: '心里线',
          params: [12, 6],
        },
        {
          type: 'sub',
          checked: false,
          name: 'VR',
          sub: '成交量变异率',
          params: [24, 30],
        },
        {
          type: 'sub',
          checked: false,
          name: 'AO',
          sub: '动量震荡指标',
          params: [5, 34],
        },
        {
          type: 'sub',
          checked: false,
          name: 'MTM',
          sub: '动量指标',
          params: [6, 10],
        },
        {
          type: 'sub',
          checked: false,
          name: 'CR',
          sub: '能量指标',
          params: [26, 10, 20, 40, 60],
        },
      ],
      options: {
        grid: {
          show: true,
          horizontal: {
            show: true,
            size: 1,
            color: '#1F2126',
            style: 'dashed',
            dashedValue: [2, 2],
          },
          vertical: {
            show: true,
            size: 1,
            color: '#1F2126',
            style: 'dashed',
            dashedValue: [2, 2],
          },
        },
        // 蜡烛图
        candle: {
          // 蜡烛图类型 'candle_solid'|'candle_stroke'|'candle_up_stroke'|'candle_down_stroke'|'ohlc'|'area'
          type: 'candle_solid',
          // 蜡烛柱
          bar: {
            upColor: '#1F2126',
            downColor: '#00F0F0',
            noChangeColor: '#888888',
            upBorderColor: '#F92855',
            downBorderColor: '#00F0F0',
            noChangeBorderColor: '#888888',
            upWickColor: '#F92855',
            downWickColor: '#00F0F0',
            noChangeWickColor: '#888888',
          },
          // 面积图
          area: {
            lineSize: 2,
            lineColor: '#2196F3',
            value: 'close',
            backgroundColor: [
              {
                offset: 0,
                color: 'rgba(33, 150, 243, 0.01)',
              },
              {
                offset: 1,
                color: 'rgba(33, 150, 243, 0.2)',
              },
            ],
          },
          priceMark: {
            show: true,
            // 最高价标记
            high: {
              show: true,
              color: '#D9D9D9',
              textOffset: 5,
              textSize: 10,
              textFamily: 'Helvetica Neue',
              textWeight: 'normal',
            },
            // 最低价标记
            low: {
              show: true,
              color: '#D9D9D9',
              textOffset: 5,
              textSize: 10,
              textFamily: 'Helvetica Neue',
              textWeight: 'normal',
            },
            // 最新价标记
            last: {
              show: true,
              upColor: '#FF3C3C',
              downColor: '#00F0F0',
              noChangeColor: '#888888',
              line: {
                show: true,
                // 'solid' | 'dashed'
                style: 'dashed',
                dashedValue: [4, 4],
                size: 1,
              },
              text: {
                show: true,
                // 'fill' | 'stroke' | 'stroke_fill'
                style: 'fill',
                size: 12,
                paddingLeft: 4,
                paddingTop: 4,
                paddingRight: 4,
                paddingBottom: 4,
                // 'solid' | 'dashed'
                borderStyle: 'solid',
                borderSize: 0,
                borderColor: 'transparent',
                borderDashedValue: [2, 2],
                color: '#FFFFFF',
                family: 'Helvetica Neue',
                weight: 'normal',
                borderRadius: 2,
              },
            },
          },
          // 提示
          tooltip: {
            // 'always' | 'follow_cross' | 'none'
            showRule: 'always',
            // 'standard' | 'rect'
            showType: 'standard',
            // 自定义显示，可以是回调方法也可以是数组，当是一个方法时，需要返回一个数组
            // 数组的子项类型为 { title, value }
            // title和value可以是字符串或者对象，对象类型为 { text, color }
            // title 或者 title.text 可以是国际化的 key，
            // value 或者 value.text 支持字符串模版
            // 例如：想显示时间，开盘和收盘，配置[{ title: 'time', value: '{time}' }, { title: 'open', value: '{open}' }, { title: 'close', value: '{close}' }]
            defaultValue: 'n/a',
            custom: [
              // { title: '开', value: '{open}' },
              // { title: '高', value: '{high}' },
              // { title: '底', value: '{low}' },
              // { title: '收', value: '{close}' },
              // { title: '量', value: '{volume}' }
            ],
            rect: {
              // 'fixed' | 'pointer'
              position: 'fixed',
              paddingLeft: 0,
              paddingRight: 0,
              paddingTop: 0,
              paddingBottom: 6,
              offsetLeft: 10,
              offsetTop: 8,
              offsetRight: 10,
              offsetBottom: 8,
              borderRadius: 4,
              borderSize: 1,
              borderColor: '#f2f3f5',
              color: '#FEFEFE',
            },
            text: {
              size: 12,
              family: 'Helvetica Neue',
              weight: 'normal',
              color: '#D9D9D9',
              marginLeft: 10,
              marginTop: 8,
              marginRight: 6,
              marginBottom: 0,
            },
            icons: [],
          },
        },
        // 技术指标
        indicator: {
          ohlc: {
            upColor: '#FF3C3C',
            downColor: '#00F0F0',
            noChangeColor: '#888888',
          },
          bars: [
            {
              // 'fill' | 'stroke' | 'stroke_fill'
              style: 'fill',
              // 'solid' | 'dashed'
              borderStyle: 'solid',
              borderSize: 1,
              borderDashedValue: [2, 2],
              upColor: '#FF3C3C',
              downColor: '#00F0F0',
              noChangeColor: '#888888',
            },
          ],
          lines: [
            {
              // 'solid' | 'dashed'
              style: 'solid',
              smooth: false,
              size: 1,
              dashedValue: [2, 2],
              color: '#FFFFFF',
            },
            {
              style: 'solid',
              smooth: false,
              size: 1,
              dashedValue: [2, 2],
              color: '#EFDA02',
            },
            {
              style: 'solid',
              smooth: false,
              size: 1,
              dashedValue: [2, 2],
              color: '#F001CC',
            },
            {
              style: 'solid',
              smooth: false,
              size: 1,
              dashedValue: [2, 2],
              color: '#0CE7E6',
            },
            {
              style: 'solid',
              smooth: false,
              size: 1,
              dashedValue: [2, 2],
              color: '#DADE7E',
            },
            {
              style: 'solid',
              smooth: false,
              size: 1,
              dashedValue: [2, 2],
              color: '#B4282A',
            },
          ],
          circles: [
            {
              // 'fill' | 'stroke' | 'stroke_fill'
              style: 'fill',
              // 'solid' | 'dashed'
              borderStyle: 'solid',
              borderSize: 1,
              borderDashedValue: [2, 2],
              upColor: 'rgba(45, 192, 142, .7)',
              downColor: 'rgba(249, 40, 85, .7)',
              noChangeColor: '#888888',
            },
          ],
          // 最新值标记
          lastValueMark: {
            show: false,
            text: {
              show: false,
              // 'fill' | 'stroke' | 'stroke_fill'
              style: 'fill',
              color: '#FFFFFF',
              size: 12,
              family: 'Helvetica Neue',
              weight: 'normal',
              // 'solid' | 'dashed'
              borderStyle: 'solid',
              borderSize: 1,
              borderDashedValue: [2, 2],
              paddingLeft: 4,
              paddingTop: 4,
              paddingRight: 4,
              paddingBottom: 4,
              borderRadius: 2,
            },
          },
          // 提示
          tooltip: {
            // 'always' | 'follow_cross' | 'none'
            showRule: 'always',
            // 'standard' | 'rect'
            showType: 'standard',
            showName: true,
            showParams: true,
            defaultValue: 'n/a',
            text: {
              size: 12,
              family: 'Helvetica Neue',
              weight: 'normal',
              color: '#D9D9D9',
              marginTop: 8,
              marginRight: 10,
              marginBottom: 0,
              marginLeft: 6,
            },
            icons: [],
          },
        },
        // x轴
        xAxis: {
          show: true,
          size: 'auto',
          // x轴线
          axisLine: {
            show: true,
            color: '#888888',
            size: 1,
          },
          // x轴分割文字
          tickText: {
            show: true,
            color: '#D9D9D9',
            family: 'Helvetica Neue',
            weight: 'normal',
            size: 12,
            marginStart: 4,
            marginEnd: 4,
          },
          // x轴分割线
          tickLine: {
            show: true,
            size: 1,
            length: 3,
            color: '#888888',
          },
        },
        // y轴
        yAxis: {
          show: true,
          size: 'auto',
          // 'left' | 'right'
          position: 'right',
          // 'normal' | 'percentage' | 'log'
          type: 'normal',
          inside: false,
          reverse: false,
          // y轴线
          axisLine: {
            show: true,
            color: '#888888',
            size: 1,
          },
          // x轴分割文字
          tickText: {
            show: true,
            color: '#D9D9D9',
            family: 'Helvetica Neue',
            weight: 'normal',
            size: 12,
            marginStart: 4,
            marginEnd: 4,
          },
          // x轴分割线
          tickLine: {
            show: true,
            size: 1,
            length: 3,
            color: '#888888',
          },
        },
        // 图表之间的分割线
        separator: {
          size: 1,
          color: '#888888',
          fill: true,
          activeBackgroundColor: 'rgba(230, 230, 230, .15)',
        },
        // 十字光标
        crosshair: {
          show: true,
          // 十字光标水平线及文字
          horizontal: {
            show: true,
            line: {
              show: true,
              // 'solid'|'dashed'
              style: 'dashed',
              dashedValue: [4, 2],
              size: 1,
              color: '#888888',
            },
            text: {
              show: true,
              // 'fill' | 'stroke' | 'stroke_fill'
              style: 'fill',
              color: '#FFFFFF',
              size: 12,
              family: 'Helvetica Neue',
              weight: 'normal',
              // 'solid' | 'dashed'
              borderStyle: 'solid',
              borderDashedValue: [2, 2],
              borderSize: 1,
              borderColor: '#686D76',
              borderRadius: 2,
              paddingLeft: 4,
              paddingRight: 4,
              paddingTop: 4,
              paddingBottom: 4,
              backgroundColor: '#686D76',
            },
          },
          // 十字光标垂直线及文字
          vertical: {
            show: true,
            line: {
              show: true,
              // 'solid'|'dashed'
              style: 'dashed',
              dashedValue: [4, 2],
              size: 1,
              color: '#888888',
            },
            text: {
              show: true,
              // 'fill' | 'stroke' | 'stroke_fill'
              style: 'fill',
              color: '#FFFFFF',
              size: 12,
              family: 'Helvetica Neue',
              weight: 'normal',
              // 'solid' | 'dashed'
              borderStyle: 'solid',
              borderDashedValue: [2, 2],
              borderSize: 1,
              borderColor: '#686D76',
              borderRadius: 2,
              paddingLeft: 4,
              paddingRight: 4,
              paddingTop: 4,
              paddingBottom: 4,
              backgroundColor: '#686D76',
            },
          },
        },
        // 覆盖物
        overlay: {
          point: {
            color: '#1677FF',
            borderColor: 'rgba(22, 119, 255, 0.35)',
            borderSize: 1,
            radius: 5,
            activeColor: '#1677FF',
            activeBorderColor: 'rgba(22, 119, 255, 0.35)',
            activeBorderSize: 3,
            activeRadius: 5,
          },
          line: {
            // 'solid' | 'dashed'
            style: 'solid',
            smooth: false,
            color: '#1677FF',
            size: 1,
            dashedValue: [2, 2],
          },
          rect: {
            // 'fill' | 'stroke' | 'stroke_fill'
            style: 'fill',
            color: 'rgba(22, 119, 255, 0.25)',
            borderColor: '#1677FF',
            borderSize: 1,
            borderRadius: 0,
            // 'solid' | 'dashed'
            borderStyle: 'solid',
            borderDashedValue: [2, 2],
          },
          polygon: {
            // 'fill' | 'stroke' | 'stroke_fill'
            style: 'fill',
            color: '#1677FF',
            borderColor: '#1677FF',
            borderSize: 1,
            // 'solid' | 'dashed'
            borderStyle: 'solid',
            borderDashedValue: [2, 2],
          },
          circle: {
            // 'fill' | 'stroke' | 'stroke_fill'
            style: 'fill',
            color: 'rgba(22, 119, 255, 0.25)',
            borderColor: '#1677FF',
            borderSize: 1,
            // 'solid' | 'dashed'
            borderStyle: 'solid',
            borderDashedValue: [2, 2],
          },
          arc: {
            // 'solid' | 'dashed'
            style: 'solid',
            color: '#1677FF',
            size: 1,
            dashedValue: [2, 2],
          },
          text: {
            // 'fill' | 'stroke' | 'stroke_fill'
            style: 'fill',
            color: '#FFFFFF',
            size: 12,
            family: 'Helvetica Neue',
            weight: 'normal',
            // 'solid' | 'dashed'
            borderStyle: 'solid',
            borderDashedValue: [2, 2],
            borderSize: 0,
            borderRadius: 2,
            borderColor: '#1677FF',
            paddingLeft: 0,
            paddingRight: 0,
            paddingTop: 0,
            paddingBottom: 0,
            backgroundColor: 'transparent',
          },
          rectText: {
            // 'fill' | 'stroke' | 'stroke_fill'
            style: 'fill',
            color: '#FFFFFF',
            size: 12,
            family: 'Helvetica Neue',
            weight: 'normal',
            // 'solid' | 'dashed'
            borderStyle: 'solid',
            borderDashedValue: [2, 2],
            borderSize: 1,
            borderRadius: 2,
            borderColor: '#1677FF',
            paddingLeft: 4,
            paddingRight: 4,
            paddingTop: 4,
            paddingBottom: 4,
            backgroundColor: '#1677FF',
          },
        },
      }
    }
  },
  watch: {
    data: {
      handler() {
        this.reloadData()
      },
      deep: true
    }
  },
  methods: {
    onChange(period) {
      this.period = period
      this.$emit('change', period)
    },
    createChart() {
      this.chart = init('chart')
    },
    optionChart() {
      if (this.period === '1min') {
        this.options.candle.type = 'area'
      } else {
        this.options.candle.type = 'candle_solid'
      }
      this.chart.setStyles(this.options)
    },
    renderMainIndicator() {
      for (let index in this.mainIndicators) {
        let item = this.mainIndicators[index]
        this.chart.removeIndicator('candle_pane', item.name)
        if (item.checked) {
          this.chart.createIndicator({
            name: item.name,
            calcParams: item.params,
            styles: item.styles || {},
          }, true, {
            id: 'candle_pane',
            isStack: true
          })
        }
      }
    },
    changeMainIndicator(name) {
      this.showPopup = false
      this.mainIndicators = this.mainIndicators.map(item => {
        item.checked = item.name === name
        return item
      })
      this.renderMainIndicator()
    },
    renderSubIndicator() {
      for (let index in this.subIndicators) {
        let item = this.subIndicators[index];
        if (item.checked) {
          this.chart.createIndicator({
            name: item.name,
            styles: item.styles || {}
          }, false, {
            id: 'pane',
            height: 40,
            dragEnabled: true
          })
        }
      }
    },
    changeSubIndicator(name) {
      this.showPopup = false
      this.subIndicators = this.subIndicators.map(item => {
        item.checked = item.name === name
        return item
      })
      this.renderSubIndicator()
    },
    reloadData() {
      this.optionChart()
      this.chart.applyNewData(this.data)
    }
  },
  mounted() {
    this.createChart()
    this.optionChart()
    this.renderMainIndicator()
    this.renderSubIndicator()
    this.reloadData()
  },
};
</script>

<style scoped>
#kline {
  color: #fff;
  background-color: #1F2126;
  text-align: center;
}

#chart {
  width: 100%;
  height: 240px;
  background-color: #1F2126;
}

#popup {
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.7);
  position: absolute;
  z-index: 9999;
  top: 0;
}

#popup > div {
  color: #303133;
  width: calc(100% - 40px);
  height: 60%;
  border-radius: 16px;
  background-color: #fff;
  text-align: left;
  position: absolute;
  left: 20px;
  top: 25%;
}

.topic {
  width: 50%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: left;
}

.iflex {
  display: inline-flex;
  justify-content: space-between;
  gap: 10px;
}

.check {
  margin: 10px;
}

.tools {
  width: calc(100% - 12px);
  background-color: #1F2126;
  padding: 3px 0;
}

.tools > div {
  cursor: pointer;
}

.title {
  width: calc(100% - 20px);
  font-size: 16px;
  font-weight: 700;
  margin: 10px;
}

.index {
  height: 36%;
  overflow-y: auto;
}

.close {
  cursor: pointer;
  font-size: 24px;
  margin-top: -4px;
}
</style>
